// Global menu registry & helpers
// - registerMenu(id, items)
// - getMenu(id)
// - buildDefaultMenus(i18n)
// - registerSubmenu(id, itemsOrFactory)
// - getSubmenu(id, ctx)
// - composeMenu(descriptor, ctx) → expanded items list
// - onOpenContextMenu(cb), openContextMenu(descriptor, at, ctx) → global context menu bus
// - Menu item shape: { id, label, action?, submenu?, enabled?, visible?, accelerator?, when? }

import { triggerAction, registerShortcut } from './hotkeys';
import { useMenuStore } from '../stores/menu';
import { getRecentMenuItems, loadRecents } from './recents';

const menuMap = new Map(); // stores raw menu definitions
const submenuMap = new Map(); // reusable submenu registry
let acceleratorDisposers = [];
const contextMenuListeners = new Set();
let lastContext = null;

export function registerSubmenu(id, itemsOrFactory) {
  submenuMap.set(id, itemsOrFactory);
  return () => submenuMap.delete(id);
}

export async function getSubmenu(id, ctx) {
  const entry = submenuMap.get(id);
  if (!entry) return [];
  try { 
    if (Array.isArray(entry)) return entry;
    const result = entry(ctx);
    return Promise.resolve(result).then(r => r || []).catch(() => []);
  } catch { return []; }
}

function evaluateVisibility(item, ctx) {
  if (typeof item.visible === 'function') {
    try { return !!item.visible(ctx); } catch { return false; }
  }
  return item.visible !== false;
}

function evaluateEnabled(item, ctx) {
  if (typeof item.enabled === 'function') {
    try { return !!item.enabled(ctx); } catch { return false; }
  }
  return item.enabled !== false;
}

async function expandMenuItems(items, ctx) {
  const out = [];
  for (const it of items || []) {
    if (!it) continue;
    if (it.label === '-') { out.push(it); continue; }
    // reference reusable submenu
    if (it.use || it.ref) {
      const id = it.use || it.ref;
      const sub = await getSubmenu(id, { ...(ctx||{}), args: it.args });
      const expanded = await expandMenuItems(sub, ctx);
      out.push(...expanded);
      continue;
    }
    if (Array.isArray(it.submenu)) {
      const expandedSubmenu = await expandMenuItems(it.submenu, ctx);
      out.push({ ...it, submenu: expandedSubmenu });
      continue;
    }
    // filter visibility
    if (!evaluateVisibility(it, ctx)) continue;
    // annotate enabled state
    out.push({ ...it, enabled: evaluateEnabled(it, ctx) });
  }
  return out;
}

export async function composeMenu(descriptor, ctx) {
  if (!descriptor) return [];
  if (typeof descriptor === 'string') return await expandMenuItems(menuMap.get(descriptor) || [], ctx);
  if (Array.isArray(descriptor)) return await expandMenuItems(descriptor, ctx);
  if (descriptor.use || descriptor.ref) return await expandMenuItems([descriptor], ctx);
  return await expandMenuItems([descriptor], ctx);
}

export function onOpenContextMenu(cb) {
  contextMenuListeners.add(cb);
  return () => contextMenuListeners.delete(cb);
}

export function openContextMenu(descriptor, at, ctx) {
  composeMenu(descriptor, ctx).then(items => {
    const payload = { items, at, ctx };
    lastContext = ctx || null;
    try { useMenuStore().setContext(ctx); } catch {}
    for (const cb of contextMenuListeners) {
      try { cb(payload); } catch {}
    }
  });
}

export function getCurrentContext() { return lastContext; }

export async function registerMenu(id, items) {
  menuMap.set(id, items || []);
  if (id === 'menubar') {
    try { useMenuStore().setMenubar(await getMenu('menubar')); } catch {}
    // rebind accelerators to global hotkey system
    for (const d of acceleratorDisposers) try { d(); } catch {}
    acceleratorDisposers = [];
    // flatten current effective items (already expanded use/ref)
    const expanded = await composeMenu(items || [], {});
    const flat = [];
    for (const m of expanded) {
      if (m && Array.isArray(m.submenu)) flat.push(...m.submenu);
    }
    for (const it of flat) {
      if (it && it.accelerator && it.action && it.label !== '-') {
        const dispose = registerShortcut({ combo: it.accelerator, action: it.action, allowInInputs: true });
        acceleratorDisposers.push(dispose);
      }
    }
  }
  return () => menuMap.delete(id);
}

export async function getMenu(id) {
  // return composed (expanded) menu for direct rendering
  return await composeMenu(menuMap.get(id) || [], {});
}

export async function buildDefaultMenus(t) {
  // reusable submenu examples
  registerSubmenu('view.toggles', [
    { id: 'view.toggleMain', label: t ? t('menu.toggle_sidebar') : 'Toggle Sidebar', action: 'toggle-main', accelerator: 'mod+b' },
    { id: 'view.toggleBottom', label: t ? t('menu.toggle_panel') : 'Toggle Panel', action: 'toggle-bottom', accelerator: 'mod+`' },
    { id: 'view.toggleAi', label: t ? t('menu.toggle_ai') : 'Toggle AI', action: 'toggle-ai', accelerator: 'mod+j' },
  ]);

  // recent submenu factory (async; data loaded on demand)
  registerSubmenu('file.recent', async () => {
    try {
      return await getRecentMenuItems(t);
    } catch (error) {
      console.warn('Failed to load recent items:', error);
      return [{ id: 'recent.error', label: 'Failed to load recent items', enabled: false }];
    }
  });

  // Explorer context menu (reusable)
  registerSubmenu('explorer.context', (ctx) => {
    const items = [
      { id: 'explorer.open', label: t ? (t('menu.open') || 'Open') : 'Open', action: 'file:openPath' },
      { id: 'sep1', label: '-' },
      { id: 'explorer.reveal', label: t ? (t('menu.reveal_in_explorer') || 'Reveal in Explorer') : 'Reveal in Explorer', action: 'file:revealInExplorer' },
      { id: 'explorer.openInTerminal', label: t ? (t('menu.open_in_terminal') || 'Open in Integrated Terminal') : 'Open in Integrated Terminal', action: 'file:openInTerminal' },
      { id: 'sep2', label: '-' },
      { id: 'explorer.newFile', label: t ? (t('menu.new_file') || 'New File') : 'New File', action: 'explorer:newFileInline' },
      { id: 'explorer.newFolder', label: t ? (t('menu.new_folder') || 'New Folder') : 'New Folder', action: 'explorer:newFolderInline' },
      { id: 'explorer.rename', label: t ? (t('menu.rename') || 'Rename') : 'Rename', action: 'fs:rename' },
      { id: 'explorer.delete', label: t ? (t('menu.delete') || 'Delete') : 'Delete', action: 'fs:delete' },
    ];
    return items;
  });

  // Editor tab context menu
  registerSubmenu('editor.tab.context', (ctx) => {
    const tab = ctx?.tab || null;
    const items = [
      { id: 'tab.close', label: t ? (t('menu.close_editor') || 'Close Editor') : 'Close Editor', action: 'editor:tab:close' },
      { id: 'tab.closeOthers', label: t ? (t('menu.close_others') || 'Close Others') : 'Close Others', action: 'editor:tab:closeOthers' },
      { id: 'tab.closeRight', label: t ? (t('menu.close_to_right') || 'Close to Right') : 'Close to Right', action: 'editor:tab:closeRight' },
      { id: 'sep1', label: '-' },
      { id: 'tab.splitRight', label: t ? (t('app.split_editor') || 'Split Editor') : 'Split Editor', action: 'editor:tab:splitRight' },
    ];
    if (tab && tab.path) {
      items.push({ id: 'sep2', label: '-' });
      items.push({ id: 'tab.reveal', label: t ? (t('menu.reveal_in_explorer') || 'Reveal in Explorer') : 'Reveal in Explorer', action: 'file:revealInExplorer' });
    }
    return items;
  });

  // Problems panel item context menu
  registerSubmenu('problems.item.context', (ctx) => {
    const p = ctx?.problem || null;
    const t = ctx?.t || null;
    const items = [
      { id: 'problems.copyMessage', label: t ? (t('problems.copy_message') || 'Copy Message') : 'Copy Message', action: 'problems:copyMessage', enabled: !!(p && p.message) },
    ];
    if (p && p.file) {
      items.push({ id: 'problems.copyPath', label: t ? (t('problems.copy_file_path') || 'Copy File Path') : 'Copy File Path', action: 'problems:copyRelativePath', enabled: true });
      items.push({ id: 'problems.copyAllInPath', label: t ? (t('problems.copy_all_messages') || 'Copy All Messages in Current Path') : 'Copy All Messages in Current Path', action: 'problems:copyAllUnderPath', enabled: true });
    }
    return items;
  });

  await registerMenu('menubar', [
    {
      id: 'file', label: t ? t('menu.file') : 'File', submenu: [
        { id: 'file.new', label: t ? t('menu.new_file') : 'New File', action: 'file:new', accelerator: 'mod+n' },
        { id: 'file.openFile', label: t ? (t('menu.open_file') || 'Open File...') : 'Open File...', action: 'file:openFile', accelerator: 'mod+o' },
        { id: 'file.openFolder', label: t ? (t('menu.open_folder') || 'Open Folder...') : 'Open Folder...', action: 'file:openFolder' },
        { id: 'file.openRecent', label: t ? (t('menu.open_recent') || 'Open Recent') : 'Open Recent', submenu: [ { use: 'file.recent' } ] },
        { id: 'file.save', label: t ? t('menu.save') : 'Save', action: 'file:save', accelerator: 'mod+s' },
        { id: 'file.saveAs', label: t ? (t('menu.save_as') || 'Save As...') : 'Save As...', action: 'file:saveAs', accelerator: 'mod+shift+s' },
        { id: 'file.saveAll', label: t ? (t('menu.save_all') || 'Save All') : 'Save All', action: 'file:saveAll', accelerator: 'mod+alt+s' },
        { id: 'sep1', label: '-' },
        { id: 'file.close', label: t ? (t('menu.close_editor') || 'Close Editor') : 'Close Editor', action: 'file:close', accelerator: 'mod+w' },
        { id: 'file.closeWindow', label: t ? (t('menu.close_window') || 'Close Window') : 'Close Window', action: 'app:closeWindow', accelerator: 'mod+shift+w' },
        { id: 'file.reopenClosed', label: t ? (t('menu.reopen_closed') || 'Reopen Closed Editor') : 'Reopen Closed Editor', action: 'file:reopenClosed', accelerator: 'mod+shift+t' },
        { id: 'sep2', label: '-' },
        { id: 'file.preferences', label: t ? (t('menu.preferences') || 'Preferences') : 'Preferences', action: 'app:preferences', accelerator: 'mod+,' },
        { id: 'file.exit', label: t ? t('menu.exit') : 'Exit', action: 'app:exit' },
      ]
    },
    {
      id: 'view', label: t ? t('menu.view') : 'View', submenu: [
        { use: 'view.toggles' },
        { id: 'view.panelTerminal', label: 'Terminal', action: 'panel:terminal' },
        { id: 'view.panelProblems', label: 'Problems', action: 'panel:problems' },
        { id: 'view.panelOutput', label: 'Output', action: 'panel:output' },
      ]
    },
    {
      id: 'help', label: t ? t('menu.help') : 'Help', submenu: [
        { id: 'help.about', label: t ? t('menu.about') : 'About', action: 'app:about' }
      ]
    }
  ]);
}

export function invokeMenuAction(item, event) {
  if (!item || item.label === '-' || item.submenu) return false;
  if (item.action) return triggerAction(item.action, event);
  return false;
}


